# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/7/24

library(ggrepel)
library(optparse)
library(magrittr)
library(ggpubr)
library(tidyverse)
library(FSA)
library(RJSONIO)
library(car)

createWhenNoExist <- function(f) {
  !dir.exists(f) && dir.create(f)
}

option_list <- list(
  make_option("--i", default = "AllMet_Raw.txt", type = "character", help = "metabolite data file"),
  make_option("--g", default = "group.txt", type = "character", help = "sample group file"),
  make_option("--config", default = "config.json", type = "character", help = "config file")
)
opt <- parse_args(OptionParser(option_list = option_list))

args <- commandArgs(trailingOnly = F)
scriptPath <- dirname(sub("--file=", "", args[grep("--file", args)]))
source(str_c(scriptPath, "/base.R"))

configJson <- fromJSON(opt$config)

diffMethod <- configJson$method
fcMethod <- configJson$fcMethod
isInter <- configJson$isInter %>%
  as.logical()
execTrend <- configJson$execTrend %>%
  as.logical()
mcInfoList <- configJson$mcInfos
groupSort <- configJson$groups
trendMethod <- configJson$trendMethod
isPaired <- configJson$isPaired %>%
  as.logical()

options(digits = 3)

sampleInfo <- read_tsv(opt$g) %>%
  rename(SampleID = Sample) %>%
  select(c("SampleID", "ClassNote")) %>%
  mutate(ClassNote = factor(ClassNote, levels = unique(ClassNote)))

groups <- unique(sampleInfo$ClassNote)

data <- read_tsv(opt$i) %>%
  rename(Metabolite = 1) %>%
  gather("SampleID", "Value", -Metabolite) %>%
  inner_join(sampleInfo, by = c("SampleID")) %>%
  filter(ClassNote %in% groups)

sampleIds <- sampleInfo$SampleID


parent <- paste0("./")

getPList <- function(name) {
  pData <- data %>% filter(Metabolite == name)
  maxY <- max(pData$Value)
  minY <- min(pData$Value)
  yHeight <- (maxY - minY)
  pValueDf <- pValueData %>% filter(Metabolite == name)

  dfMethod <- pValueDf$test.method
  testTb <- if (dfMethod == "anova" || dfMethod == "anova.tukey") {
    test <- aov(Value ~ ClassNote, data = pData)
    testTb <- TukeyHSD(test) %>%
      .$ClassNote %>%
      as.data.frame() %>%
      rownames_to_column("group") %>%
      rowwise() %>%
      do({
        result <- as_tibble(.)
        vs <- result$group %>%
          as.character() %>%
          str_split("-") %>%
          unlist() %>%
          str_trim()
        group1 <- vs[1]
        group2 <- vs[2]
        result %>%
          mutate(group1 = group1, group2 = group2, method = "tukey")
      }) %>%
      ungroup()
    testTb
  }else if (dfMethod == "kruskal.test" || dfMethod == "kruskal.test.dunn") {
    testTb <- tryCatch({
      dunnTest(Value ~ ClassNote, data = pData) %>%
        .$res %>%
        as_tibble() %>%
        rename(group = Comparison, `p adj` = P.unadj) %>%
        rowwise() %>%
        do({
          result <- as_tibble(.)
          vs <- result$group %>%
            as.character() %>%
            str_split("-") %>%
            unlist() %>%
            str_trim()
          group1 <- vs[1]
          group2 <- vs[2]
          result %>%
            mutate(group1 = group1, group2 = group2, method = "dunn")
        }) %>%
        ungroup()
    }, error = function(e) {
      tb <- pData$ClassNote %>%
        unique() %>%
        as.character() %>%
        combn(2) %>%
        asplit(2) %>%
        map_dfr(function(groups) {
          tibble(group1 = groups[1], group2 = groups[2], `p adj` = 1, method = "dunn")
        })
      tb
    })

    testTb
  }

  testTb <- testTb %>%
    rename(p = `p adj`) %>%
    mutate(i = 1:n()) %>%
    rowwise() %>%
    do({
      result <- as_tibble(.)
      i <- result$i
      p <- result$p
      y.position <- maxY + yHeight * (i) * 0.1
      p.signif <- if (p < 0.0001) "***" else if (p < 0.01) "**" else if (p < 0.05) "*" else "ns"
      result %>%
        mutate(p.signif = p.signif, y.position = y.position)
    }) %>%
    ungroup() %>%
    filter(p.signif != "ns")

  outTestTb <- testTb %>%
    mutate(Metabolite = name)
  list(testTb = outTestTb)
}

fileName <- paste0(parent, "/AllMet_Test.csv")

pValueData <- read.csv(fileName, header = T, stringsAsFactors = F, comment.char = "") %>%
  arrange(P)
names <- pValueData$Metabolite

list <- names %>%
  map(getPList)

testTb <- list %>%
  map_dfr(function(l) {
    l$testTb
  })

userTestTb <- testTb %>%
  select(-c("y.position")) %>%
  select(c("Metabolite", "group1", "group2", "p", "p.signif"), everything()) %>%
  select_if(!(names(.) %in% (c("group", "diff", "lwr", "upr", "i", "Z", "P.adj"))))

write_csv(userTestTb, "post_hoc.csv")
write_csv(testTb, "testTb_post_hoc.csv")
